package com.guoju.tyframework.mvc.providers;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import com.guoju.tyframework.mvc.ServletConstants;
import com.guoju.tyframework.mvc.config.ActionConfiguration;
import com.guoju.tyframework.mvc.config.BeanProperty;
import com.guoju.tyframework.mvc.config.MvcBeans;
import com.guoju.tyframework.mvc.utils.CommonUtils;
import com.guoju.tyframework.mvc.utils.ServletUtil;

public class ActionXmlProvider {
	
	public static Element getRootByPath(String xmlPath) throws JDOMException, IOException{
		SAXBuilder builder=new SAXBuilder();
		Document document=builder.build(new File(xmlPath));
		Element root=document.getRootElement();
		return root;
		
	}
	public static Map<String,ActionConfiguration> doResolve(String xmlPath) throws JDOMException, IOException{
		Map<String,ActionConfiguration> map=new HashMap<String,ActionConfiguration>();
		Element root=getRootByPath(xmlPath);
		Element actionMapping=root.getChild("action-mapping");
		List<Element> mappings=actionMapping.getChildren();
		for(Element mapping:mappings){
			String name=mapping.getAttributeValue("name");
			String type=mapping.getAttributeValue("type");
			String path=mapping.getAttributeValue("path");
			ActionConfiguration config=new ActionConfiguration(name, type, path);
			
			//取得result
			List<Element> actionResults=mapping.getChildren();
			Map<String,String> mapResults=new HashMap<String,String>();
			for (Element result : actionResults) {
				String resultName=result.getAttributeValue("name");
				String resultValue=result.getAttributeValue("value");
				if(CommonUtils.isEmpty(resultValue)){
					resultValue=result.getText();
				}
				mapResults.put(resultName, resultValue);
			}
			config.setResults(mapResults);
			
			//设置actionBean
			List<Element> beans=root.getChild("beans").getChildren();
			for(Element bean:beans){
				String beanId=bean.getAttributeValue("id");
				if(beanId.equals(type)){
					String beanClass=bean.getAttributeValue("class");
					config.setActionClass(beanClass);
					MvcBeans mvcBean=new MvcBeans(beanId, beanClass);
					
					//设置mvcBean的 property
					LinkedList<BeanProperty> properties=getProperties(bean, beans);
					
					mvcBean.setProperties(properties);
					config.setActionBean(mvcBean);
					break;
				}
			}
			map.put(path, config);
		}
		return map;
	}
	
	/**
	 * 获取实体的属性节点
	 * @param bean 属性节点对应的父级bean 
	 * @param beans root.getChild("beans").getChildren()
	 * @return
	 */
	private static LinkedList<BeanProperty> getProperties(Element bean,List<Element> beans){
		List<Element> propertyElements=bean.getChildren();
		LinkedList<BeanProperty> properties=new LinkedList<BeanProperty>();
		for (Element p : propertyElements) {
			String pname=p.getAttributeValue("name");
			String pref=p.getAttributeValue("ref");
			String ptype=p.getAttributeValue("type");
			BeanProperty property=new BeanProperty(pname, pref, ptype);
			//如果设置了ref没有设置type 则找到ref对应的class给type赋值
			//TODO 此处应该递归 设置ref为实体 不应该只存储对应的id 难 啊
			if(CommonUtils.isEmpty(ptype)&&CommonUtils.isNotEmpty(pref)){
				for(Element refbean:beans){
					String refId=refbean.getAttributeValue("id");
					if(refId.equals(pref)){
						String refClass=refbean.getAttributeValue("class");
						property.setType(refClass);
					}
				}
			}
			properties.add(property);
		}
		return properties;
	}
	
	public static MvcBeans getBeansByid(String id,HttpServletRequest req) throws JDOMException, IOException{
		MvcBeans mvcBean=null;
		ServletContext context=req.getServletContext();
		String xmlPath=ServletUtil.getXmlFilePath(context);
		Element root=getRootByPath(xmlPath);
		List<Element> beans=root.getChild("beans").getChildren();
		for(Element e:beans){
			String beanId=e.getAttributeValue("id");
			if(beanId.equals(id)){
				mvcBean=new MvcBeans(id, e.getAttributeValue("class"));
				
				LinkedList<BeanProperty> properties=getProperties(e, beans);
				mvcBean.setProperties(properties);
				
				break;
			}
		}
		return mvcBean;
	}

}
